package zhihuilan.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.conditions.query.QueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wechat.pay.java.core.Config;
import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.RefundService;
import com.wechat.pay.java.service.refund.model.AmountReq;
import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.Status;
import org.apache.commons.lang3.time.DateUtils;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import zhihuilan.common.WxMiniResponse;
import zhihuilan.common.utils.RedisCache;
import zhihuilan.common.utils.ToolsUtils;
import zhihuilan.common.utils.WechatPayUtils;
import zhihuilan.config.WeChatPayMiniConfig;
import zhihuilan.dto.MyPayOrderDto;
import zhihuilan.entity.MyGoods;
import zhihuilan.entity.MyPayOrder;
import zhihuilan.mapper.MyGoodsMapper;
import zhihuilan.mapper.MyPayOrderMapper;
import zhihuilan.params.query.MyPayOrderQueryParam;
import zhihuilan.service.MyGoodsService;
import zhihuilan.service.MyPayOrderService;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

@Service
public class MyPayOrderServiceImpl extends ServiceImpl<MyPayOrderMapper, MyPayOrder> implements MyPayOrderService {


    @Override
    public String xcxgetPrepayId(MyPayOrderQueryParam myPayOrderQueryParam){
        MyPayOrder myPayOrder = getorderid(myPayOrderQueryParam);
        System.out.println(myPayOrder);
        return   WechatPayUtils.jsapiPay(myPayOrder);
    }

    public MyPayOrder getorderid(MyPayOrderQueryParam myPayOrderQueryParam){
        String orderId =  new Date().getTime()/1000+""+ ToolsUtils.randomStr(8);
        QueryWrapper<MyPayOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("`order`",orderId);
        MyPayOrder myPayOrder = baseMapper.selectOne( queryWrapper);
        while (myPayOrder!=null){
            orderId =  new Date().getTime()/1000+""+ ToolsUtils.randomStr(8);
            myPayOrder = baseMapper.selectOne( queryWrapper);
        }
        myPayOrder = new MyPayOrder();
        myPayOrder.setOrder(orderId);
        myPayOrder.setAmount(myPayOrderQueryParam.getAmount());
        myPayOrder.setGoodsid(myPayOrderQueryParam.getGoodsid());
        myPayOrder.setType(myPayOrderQueryParam.getType());
        myPayOrder.setTitle(myPayOrderQueryParam.getTitle());
        myPayOrder.setPlatform(myPayOrderQueryParam.getPlatform());
        myPayOrder.setCreatetime(new Date().getTime()/1000);
        myPayOrder.setCreateuser(myPayOrderQueryParam.getCreateUser());
        myPayOrder.setStatus(0);
        myPayOrder.setOpenid(myPayOrderQueryParam.getOpenId());
        myPayOrder.setGuid(myPayOrderQueryParam.getGuid());
        Integer i = baseMapper.insert(myPayOrder);
        if(i>0){
            return myPayOrder;
        }
        return null;
    }


    @Override
    public WxMiniResponse paycallback(MyPayOrderQueryParam myPayOrderQueryParam){

        if(myPayOrderQueryParam.getType()==0){
            return WxMiniResponse.error(2013, "类型不存在！");
        }
        QueryWrapper<MyPayOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order",myPayOrderQueryParam);
        MyPayOrder myPayOrder= baseMapper.selectOne(queryWrapper);
        if(myPayOrder==null){
            return WxMiniResponse.error(2013, "订单不存在！");
        }
        MyPayOrder myPayOrder1 = new MyPayOrder();
        queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order",myPayOrderQueryParam.getOrder());
        myPayOrder1.setStatus(2);
        baseMapper.update(myPayOrder1,queryWrapper);
        return WxMiniResponse.ok();
//        db('pay_order')->where(array('order'=>$order,'guid'=>$guid))->update(array("status"=>2));
//        $d['audit'] =0;
//        $d['orderid']=$order;
//        if($type==2){
//            $fac = db("factory")->where(array("staffid"=>$member['id']))->find();
//            if($fac['audit']==1){
//                $d['audit'] =1;
//            }
//            $r = db("factory")->where(array("staffid"=>$member['id']))->update($d);
//        }else if($type==1){
//            $shop = db("shop")->where(array("staffid"=>$member['id']))->find();
//            if($shop['audit']==1){
//                $d['audit'] =1;
//            }
//            $r =  db("shop")->where(array("staffid"=>$member['id']))->update($d);
//        }
//        return ret($r);
    }

    @Override
    public  MyPayOrder selectOrderByOrderId(String order){
        QueryWrapper<MyPayOrder>  queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order",order);
       return   baseMapper.selectOne(queryWrapper);
    }


    @Override
    public Integer editPayResult(MyPayOrder myPayOrder){
        QueryWrapper<MyPayOrder>  queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("order",myPayOrder.getOrder());
        return   baseMapper.update(myPayOrder,queryWrapper);
    }

    @Override
    public  Page<MyPayOrder> getOrderList(MyPayOrderQueryParam myPayOrderQueryParam){
        QueryWrapper<MyPayOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("guid",myPayOrderQueryParam.getGuid());
        if( myPayOrderQueryParam.getType()!=null&&myPayOrderQueryParam.getType()>0){
            queryWrapper.eq("type",myPayOrderQueryParam.getType());
        }
        if( myPayOrderQueryParam.getStatus()!=null&&myPayOrderQueryParam.getStatus()!=4){
            queryWrapper.eq("status",myPayOrderQueryParam.getStatus());
        }
        if( myPayOrderQueryParam.getInvoice()!=null&&myPayOrderQueryParam.getInvoice()>-1){
            queryWrapper.eq("invoice",myPayOrderQueryParam.getInvoice());
        }
        queryWrapper.gt("paymenttime",0);
        queryWrapper.orderByDesc("paymenttime");
       return   baseMapper.selectPage( new Page<>(myPayOrderQueryParam.getPage(), myPayOrderQueryParam.getPageSize()), queryWrapper) ;

    }

    @Override
    public  MyPayOrder getOrderInfoByOrderStatus(String order,Integer status){
        QueryWrapper<MyPayOrder>  queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",order);
        queryWrapper.eq("status",status);
        return   baseMapper.selectOne(queryWrapper);
    }

    @Override
    public MyPayOrderDto getOrderInfo(Integer id){
        MyPayOrder myPayOrder = baseMapper.selectById(id);
        MyPayOrderDto myPayOrderDto = new MyPayOrderDto();
        BeanUtils.copyProperties(myPayOrderDto,myPayOrder);
        return myPayOrderDto;
    }

    @Override
    public Integer updateOrderByOrder(String order){
        QueryWrapper<MyPayOrder> queryWrapper= new QueryWrapper<>();
        queryWrapper.eq("id",order);
        queryWrapper.eq("status",2);
        MyPayOrder payOrder = new MyPayOrder();
        payOrder.setInvoice(1);
        return baseMapper.update(payOrder,queryWrapper);
    }

    /**
     * 支付成功
     */
    @Override
    public  void success(MyPayOrder myPayOrder, Transaction transaction) {
        try {

            // 校验订单信息 & 支付结果 & 订单有效期止日期
            if (myPayOrder != null && myPayOrder.getType().equals(0) && myPayOrder.getPaymenttime() < 1) {
                // 构建修改对象
                MyPayOrder updateOrder = new MyPayOrder();
                updateOrder.setId(myPayOrder.getId());
                updateOrder.setPlatform(myPayOrder.getPlatform());
                updateOrder.setPaymenttime(new Date().getTime()/1000);
                updateOrder.setTransactionid(transaction.getTransactionId());
                if (editPayResult(updateOrder).equals(1)) {
                    // 删除Redis订单支付信息
//                    SpringUtils.getBean(RedisCache.class).deleteObject(Wechar.ORDER_PAY_REDIS_PREFIX + transaction.getOutTradeNo());
                }
            } else {
                // 订单信息不存在 执行退款
                 refunded(transaction);
            }
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
    }


    @Override
    public BigDecimal totalAmount(String guid){
        QueryWrapper<MyPayOrder> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("status", 2);
        queryWrapper.eq("invoice", 0);
        queryWrapper.eq("guid", guid);
        queryWrapper.select(" SUM(amount) as amount ");
        Map<String, Object> resultMap = baseMapper.selectMaps(queryWrapper).stream().findFirst().orElse(null);
        return  (resultMap != null) ? (BigDecimal) resultMap.get("amount") : BigDecimal.ZERO;
    }


    /**
     * 执行退款
     */
    @Override
    public  void refunded(Transaction transaction) {
        try {
           WeChatPayMiniConfig  weChatPayMiniConfig =new WeChatPayMiniConfig();
            // 构建退款Service
            RefundService service = new RefundService.Builder().config(weChatPayMiniConfig.getConfig()).build();
            // 构建请求对象
            CreateRequest request = new CreateRequest();
            request.setOutTradeNo(transaction.getOutTradeNo());
            request.setOutRefundNo(transaction.getOutTradeNo());
            // 支付总金额（分）
            long total = transaction.getAmount().getTotal();
            // 设置退款金额
            AmountReq amount = new AmountReq();
            amount.setRefund(total);
            amount.setTotal(total);
            amount.setCurrency("CNY");
            request.setAmount(amount);
            // 请求API申请退款
            Refund refund = service.create(request);
            // 校验退款结果
            if (refund != null && Status.SUCCESS.equals(refund.getStatus())) {
                // 退款成功
                //  log.info("微信退款成功：{}", wechatPay);
            }
        } catch (Exception e) {
            //  log.error(e.getMessage(), e);
        }
    }


}
